/**
 * @description 类型判断相关公用代码
 * 直接copy。。
 */

/*eslint-disable no-undefined*/

// get type string of a construtor function
export function getType(fn) {
  if (typeof fn === 'undefined') {
    return undefined
  }

  if (fn === null) {
    return null
  }

  const match = fn && fn.toString().match(/^\s*function (\w+)/)
  return match ? match[1] : ''
}

// get type string of a variable
export function getTypeOf(value) {
  const fn = typeof value === 'undefined'
    ? undefined : (value === null
      ? null : Object.getPrototypeOf(value).constructor)

  return getType(fn)
}

// check if a variable's type is the type provided
export function isType(type, value) {
  const typeOfValue = getTypeOf(value)
  const typeStr = getType(type)

  // async function is considered as function as well
  if (typeStr === 'Function') {
    return typeOfValue === 'Function' ||
      typeOfValue === 'AsyncFunction'
  }

  return typeOfValue === typeStr
}

const _toString = Object.prototype.toString

export function isObject(obj) {
  return obj !== null && typeof obj === 'object'
}

export function isArray(arr) {
  return Array.isArray(arr)
}

export function isPlainObject(obj) {
  return _toString.call(obj) === '[object Object]'
}

export function isNumber(obj) {
  return typeof obj === 'number' && !isNaN(obj)
}

export function isString(str) {
  if (typeof str === 'string' || str instanceof String) {
    return true
  }
  return false
}

export function isInteger(num) {
  return isType(Number, num) && Number.isInteger(num)
}

export function isDecimal(num) {
  return isType(Number, num) && !Number.isInteger(num)
}

export function isEmail(str) {
  return /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
    .test(toString(str))
}

export function isPhoneNum(str) {
  return /^\d{11}$/.test(toString(str))
}

export function isIntStr(str) {
  return /^(-|\+)?\d+$/.test(toString(str))
}

// Convert a value to a string that is actually rendered.
export function toString(val) {
  return val === null
    ? '' : (typeof val === 'object'
      ? JSON.stringify(val) : String(val))
}
